import 'dart:collection';

import 'package:flutter/material.dart';
import 'package:x3_base_core/x3_base_core.dart';
import 'package:x3_component_core/controller/base_future_controller.dart';
import 'package:x3_component_core/components/state_components/base_empty_component.dart';
import 'package:x3_component_core/components/state_components/base_loading_component.dart';

enum BaseScreenRefreshServiceType { Request, Response, Fetch, X2Microservice, X3YJbService, XML }

class BaseScreenRefreshComponent extends StatefulWidget {
  /// 请求服务的实体类
  final BaseScreenRequestModel request;

  /// 构建 widget
  final Widget Function(BaseHttpResultModel result) builder;

  /// 是否需要下拉刷新
  final bool needRefreshIndicator;

  /// 控制器
  final BaseFutureController controller;

  /// 请求类型
  final BaseScreenRefreshServiceType serviceType;

  /// 是否显示Loading加载框
  final bool showLoading;

  /// 服务报错时是否弹出报错
  final bool reportError;

  BaseScreenRefreshComponent({
    Key key,
    @required this.request,
    @required this.builder,
    this.needRefreshIndicator = false,
    this.showLoading = true,
    this.controller,
    this.serviceType = BaseScreenRefreshServiceType.Fetch,
    this.reportError = true,
  }) : super(key: key);

  @override
  _BaseScreenRefreshComponentState createState() => _BaseScreenRefreshComponentState();
}

class _BaseScreenRefreshComponentState extends State<BaseScreenRefreshComponent> with BaseFutureBuilderUtil {
  /// 刷新控制器
  BaseFutureController _controller;

  /// 获取当前的控制器
  BaseFutureController get _effectiveController => widget.controller ?? _controller;

  Future<BaseHttpResultModel> _future;

  @override
  void initState() {
    if (widget.controller == null) _controller = new BaseFutureController();
    _effectiveController.addListener(() => this._onRefresh());
    this._future = this._buildFutureMethod();
    super.initState();
  }

  /// 请求
  Future<BaseHttpResultModel> _buildFutureMethod() {
    Map<String, dynamic> params = new HashMap();
    params.addAll(widget.request.params);
    params.addAll(_effectiveController.params);
    switch (widget.serviceType) {
      case BaseScreenRefreshServiceType.Fetch:
        return dioUtil.fetch(widget.request.path, method: widget.request.method, params: params, showToast: widget.reportError);
        break;
      case BaseScreenRefreshServiceType.Request:
        const String service = '/x3-service-archives-center/archive/v1/request/get/list';
        return _buildFuture(service);
        break;
      case BaseScreenRefreshServiceType.X2Microservice:
        return dioX2Util.fetchX2Microservice(widget.request.path, method: widget.request.method, params: params);
        break;
      case BaseScreenRefreshServiceType.X3YJbService:
        return dioX2Util.fetchX3YjbService(widget.request.path, method: widget.request.method, params: params);
        break;
      case BaseScreenRefreshServiceType.XML:
        return dioX2Util.fetchXMLService(widget.request.path, method: widget.request.method, params: params);
        break;
      case BaseScreenRefreshServiceType.Response:
        const String service = '/x3-service-archives-center/archive/user/v1/response/get/list';
        return _buildFuture(service);
        break;
    }
    return null;
  }

  @override
  Widget build(BuildContext context) {
    return widget.needRefreshIndicator == true ? RefreshIndicator(onRefresh: _onRefresh, child: _buildFutureWidget(), color: Theme.of(context).primaryColor) : _buildFutureWidget();
  }

  Widget _buildFutureWidget() {
    return FutureBuilder(key: widget.key, future: _future, builder: (BuildContext context, AsyncSnapshot<dynamic> asyncSnapshot) => buildFutureBuilder(asyncSnapshot, showLoading: widget.showLoading, builder: widget.builder));
  }

  /// 下拉刷新
  Future<void> _onRefresh() async {
    setState(() {
      this._future = this._buildFutureMethod();
    });
  }

  /// 出入参方法
  Future<BaseHttpResultModel> _buildFuture(String service) {
    String method = BaseTransformUtil.enumToString(widget.request.method);
    String path = method + (widget.request.path.startsWith('/') ? widget.request.path : '/' + widget.request.path);
    return dioUtil.fetch(service, params: {'appApiUrlId': path}, method: BaseHttpMethodEnum.POST, showToast: widget.reportError);
  }

  @override
  void dispose() {
    if (_controller != null) _controller.dispose();
    super.dispose();
  }
}

/// FutureBuilder builder 过滤方法
class BaseFutureBuilderUtil {
  /// 单个返回
  Widget buildFutureBuilder(AsyncSnapshot asyncSnapshot, {@required Widget Function(BaseHttpResultModel result) builder, bool showLoading = true}) {
    switch (asyncSnapshot.connectionState) {
      case ConnectionState.waiting: // 请求开始
        return showLoading == true ? BaseLoadingComponent() : Text('');
      case ConnectionState.done:
        if (asyncSnapshot.hasError) {
          return Center(child: Text('Error: ${asyncSnapshot.error}'));
        }
        BaseHttpResultModel result = asyncSnapshot.data;
        if (result.success == true) {
          return builder(result);
        }
        return Center(child: Text('Error: ${result.data}'));
      default:
        return BaseEmptyComponent();
    }
  }

  /// 多个返回
  Widget buildMultipleFutureBuilder(AsyncSnapshot asyncSnapshot, {@required Widget Function(List<BaseHttpResultModel> result) builder, bool showLoading = true}) {
    switch (asyncSnapshot.connectionState) {
      case ConnectionState.waiting: // 请求开始
        return showLoading == true ? BaseLoadingComponent() : Text('');
      case ConnectionState.done:
        if (asyncSnapshot.hasError) {
          return Center(child: Text('Error: ${asyncSnapshot.error}'));
        }
        List<dynamic> list = asyncSnapshot.data;
        List<BaseHttpResultModel> result = list.map((e) => e as BaseHttpResultModel).toList();
        if (result.every((element) => element.success == true)) {
          return builder(result);
        }
        return Center(child: Text('Error: 请求失败'));
      default:
        return BaseEmptyComponent();
    }
  }
}
